﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Net;
using System.IO;

using NetMonitor.ClassLib;
using NetMonitor.Server;

namespace NetMonitor.NetApp
{
    public partial class MainForm : Form
    {

        #region 变量
        /// <summary>
        /// 定义一个pool，容纳所有节点
        /// </summary>
        List<MyPoint> pointPoll;
        /// <summary>
        /// 定义一个pool，容纳所有标题Lable控件
        /// </summary>
        List<Label> titlePoll;

        /// <summary>
        /// 定义序号，用来纪录池中节点的数量
        /// </summary>
        public int index = 0;

        /// <summary>
        /// 表示用户选择了几个点，如果选择了两个就划线并归零
        /// </summary>
        private int howManyPointSelect = 0;

        /// <summary>
        /// 一个像素点，纪录用户鼠标动作的坐标
        /// </summary>
        Point recordPoint = new Point();

        /// <summary>
        /// 确定是否可以增加新的节点,当划线按钮按下时不可以新增节点
        /// </summary>
        bool canAddNewPoint = true;

        /// <summary>
        /// 确定用户鼠标是否点下的某个节点
        /// </summary>
        bool whetherSelected = false;

        /// <summary>
        /// 确定节点是否可以移动
        /// </summary>
        bool canMovement = true;

        /// <summary>
        /// 初始化自定义的类节点---MyPoint,用户当前选取的MP的实例
        /// </summary>
        MyPoint selectMp;

        /// <summary>
        /// 用户用户当前选定的Lable实例
        /// </summary>
        Label selectLb;

        /// <summary>
        /// 缓存两个节点，用于划线
        /// </summary>
        private MyPoint point1;

        /// <summary>
        /// 缓存两个节点，用于划线
        /// </summary>
        private MyPoint point2;

        /// <summary>
        /// 节点标题的颜色
        /// </summary>
        Color lbColor;

        /// <summary>
        /// 节点标题的字体
        /// </summary>
        Font lbFont;

        /// <summary>
        /// 线路的颜色
        /// </summary>
        Color lineColor;

        /// <summary>
        /// 线路的宽度
        /// </summary>
        int lineWidth ;


        /// <summary>
        /// 构造函数
        /// </summary>
        public MainForm()
        {
            InitializeComponent();
            pointPoll = new List<MyPoint>();
            titlePoll = new List<Label>();

            //初始设置划线颜色为绿色,宽度为
            lineColor = Color.Green;
            lineWidth = 2;
            curLineColor = lineColor;
            // 
            lbColor = Color.Black;            
            lbFont = new Font("arial", 11);
            map = smallMap;
            //
            this.MouseWheel += new MouseEventHandler(this.MainForm_MouseWheel);
            SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw, true);
            UpdateStyles();            
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            this.mi_Property.Checked = tsm_Property.Checked = true;
            this.menuStrip1.Focus();
            this.tsm_ExitFullScreen.Enabled = false;
            //
            tsm_ChangeBackImage.Enabled = false;
            mi_BackgroundChange.Enabled = false;
            //
            mapMoveHor = (map.Width - this.Width) / 2;
            mapMoveVer = (map.Height - this.Height) / 2;
        }


        #region 地区\接入节点没有拖入主窗体，鼠标拖动节点的相应动作

        private bool addPointSelected = false;
        void pb_IconSmall_MouseDown(object sender, MouseEventArgs e)
        {           
            if (isEditable && canAddNewPoint && e.Button.Equals(MouseButtons.Left))
            {
                addPointSelected = true;
                recordPoint = Cursor.Position;
                initialX = ((Control)sender).Left;
                initialY = ((Control)sender).Top;
                if (((Control)sender).Width > 28)
                    initialT = 1;
                else if (((Control)sender).Width > 19)
                    initialT = 2;
                else
                    initialT = 3;                
            }           
        }

        private int initialX = 0;
        private int initialY = 0;
        private int initialT = 0;

        void pb_IconSmall_MouseMove(object sender, MouseEventArgs e)
        {
            if (isEditable && canAddNewPoint && addPointSelected && e.Button.Equals(MouseButtons.Left))
            {            
                ((Control)sender).Left += Cursor.Position.X - recordPoint.X;
                ((Control)sender).Top += Cursor.Position.Y - recordPoint.Y;                                    
                recordPoint = Cursor.Position;

                if (((Control)sender).Right >= StaticPar.leftPanelWidth)
                    Cursor = Cursors.Cross;
                else
                    Cursor = Cursors.Default;
            }    
        }


        void pb_IconSmall_MouseUp(object sender, MouseEventArgs e)
        {
            if (isEditable && canAddNewPoint && e.Button.Equals(MouseButtons.Left))
            {
                addPointSelected = false;
                this.Cursor = Cursors.Default;
                ((Control)sender).Left = initialX;
                ((Control)sender).Top = initialY;

                recordPoint = Cursor.Position;
                //如果鼠标的释放坐标位于右侧窗体,则增加一个节点
                if (Cursor.Position.X > StaticPar.leftPanelWidth)
                {
                    PropertyForm pf = new PropertyForm();
                    pf.Location = recordPoint;
                    if (pf.Bottom > this.Bottom)
                        pf.Top = this.Bottom - pf.Height - 10;
                    if (pf.Right > this.Right)
                        pf.Left = this.Right - pf.Width - 10;

                    pf.ShowDialog();
                    if (pf.DialogResult == DialogResult.OK && pf.IsValidate)
                    {
                        int x = recordPoint.X - this.Left;
                        int y = recordPoint.Y - this.Top - 28;

                        MyPoint mp = addPoint(caculateMapPoint(new Point(x, y)), pf.PointName, pf.PointLocation, pf.PointIpaddress, initialT);
                        mp.StartTimer();

                        filterPoints(scale);
                    }
                        
                    lb_PointCount.Text = pointPoll.Count.ToString();
                }
            }            
        }


        #endregion


        /// <summary>
        /// 检测是否含有重复的节点
        /// </summary>
        /// <param name="pointName"></param>
        /// <returns>true则有该节点存在,false没有节点存在</returns>
        public bool IfHasPoint(string pointName)
        {            
            foreach (MyPoint item in pointPoll)
                if (item.PointName.Equals(pointName))
                    return true;           
            return false;
        }


        #region 节点拖入主窗体后，鼠标点击的相应方法

        private List<PointLine> pointLines = new List<PointLine>();

        void mp_MouseDown(object sender, MouseEventArgs e)
        {
            //判断选择的是否是节点对象
            if (sender.GetType().Equals(typeof(MyPoint)))
            {
                selectMp = (MyPoint)sender;
                selectLb = findLabel(selectMp.PointName);
                
                if (e.Button.Equals(MouseButtons.Right) || !isEditable)
                    return;

                whetherSelected = true;

                //在不能移动的情况下,表示划线
                //如果划线的情况下,第一次点击的节点赋给MyPoint1实例,第二次点击的节点赋给MyPoint2实例
                //之后在两个节点之间划线             
                if (!canMovement)
                {
                    if (howManyPointSelect == 0 || point1 == null)
                    {
                        point1 = (MyPoint)sender;
                        howManyPointSelect = 1;
                    }
                    else
                    {
                        point2 = (MyPoint)sender;
                        if (point2.Equals(point1))
                        {
                            point2 = null;
                            return;
                        }

                        //如果两个节点都不为空,point1和point2不指向同一个实例,才可以开始划线
                        //画完线之后，互相添加各自的实例入ArrayList
                        if (point1 != null)
                        {
                            if (point1.CheckIfhasMyPoint(point2) || point2.CheckIfhasMyPoint(point1))
                            {
                                point1.myDrawLinePoll.Remove(point2);                                
                                point2.myDrawLinePoll.Remove(point1);


                                foreach (PointLine l in pointLines)
                                {
                                    if (l.myEquals(point1, point2))
                                    {
                                        pointLines.Remove(l);
                                        break;
                                    }
                                }

                                refreshTooltips();
                                Invalidate();
                            }
                            else 
                            {
                                point1.myDrawLinePoll.Add(point2);
                                point2.myDrawLinePoll.Add(point1);

                                if (curLineColor != lineColor)
                                    pointLines.Add(new PointLine(point1, point2, curLineColor));

                                refreshTooltips();
                                Invalidate();
                            }
                            point1 = null;
                            point2 = null;
                            howManyPointSelect = 0;
                        }
                    }
                }
                else//不划线的情况下,更改光标
                {
                    ////记录下起点的位置
                    recordPoint = Cursor.Position;
                    
                    try
                    {
                        if (selectMp.PointType == 1)
                        {
                            Cursor cu = new Cursor(Properties.Resources.select301.Handle);
                            this.Cursor = cu;
                        }
                        else
                        {
                            Cursor cu = new Cursor(Properties.Resources.select201.Handle);
                            this.Cursor = cu;
                        }   
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("光标文件加载失败,详细信息:" + ex.Message);
                        return;
                    }
                    selectMp.Visible = false;
                    selectLb.Visible = false;
                }
            }
        }


        void mp_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button.Equals(MouseButtons.Left) && sender.GetType().Equals(typeof(MyPoint)) && whetherSelected)
                if (isEditable && canMovement)
                {
                    Point recordPoint = new Point(Cursor.Position.X, Cursor.Position.Y);
                    recordPoint.Offset(-this.Left, -this.Top - 28);
                    whetherSelected = false;

                    Cursor = Cursors.Default;
                    selectMp.Visible = true;
                    selectLb.Visible = true;

                    movePoint(selectMp, recordPoint);                    
                }            
        }

        #endregion


        #region 文件下拉菜单
        /// <summary>
        /// 打开 按钮定义
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mi_Open_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                clear();

                try
                {
                    Stream myStream1;
                    if ((myStream1 = openFileDialog1.OpenFile()) != null)
                    {
                        StreamReader sr = new StreamReader(myStream1);
                        SuspendLayout();

                        open(sr);

                        refreshTooltips();                        
                        lb_PointCount.Text = pointPoll.Count.ToString();
                        
                        //
                        currentfile = openFileDialog1.FileName;
                        sr.Close();
                        myStream1.Close();

                        filterPoints(scale);
                        ResumeLayout();

                        foreach (MyPoint p in pointPoll)
                            p.StartTimer();
                    }

                    Invalidate();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("打开文件失败,详细原因: " + ex.Message);
                    System.Console.Out.WriteLine(ex.StackTrace);
                }
            }
        }


        private void MenuItemConnect_Click(object sender, EventArgs e)
        {
            ServerIpForm sif = new ServerIpForm();
            if (sif.ShowDialog() == DialogResult.OK)
            {                
                clear();
                TextReader tr = new StringReader(NetMonClient.GetClient(sif.IpAddress).readConfig());
                SuspendLayout();

                open(tr);

                refreshTooltips();
                lb_PointCount.Text = pointPoll.Count.ToString();

                tr.Close();

                filterPoints(scale);
                ResumeLayout();

                foreach (MyPoint p in pointPoll)
                    p.startCheckServer();
            }
        }

        private void open(TextReader sr)
        {
            string[] tokens;
            string Line, id, name, location, ip;
            int j, x, y, img = 0, pointtype;
            //读取节点信息
            while ((Line = sr.ReadLine()) != null)
            {
                tokens = Line.Split(' ');

                if (tokens.Length > 1)
                {
                    j = 0;
                    id = "";
                    if (tokens[j].IndexOf("(") == 0)
                    {
                        string temp = tokens[j++];
                        id = temp.Substring(1, temp.Length - 2);
                    }
                    name = tokens[j++];
                    location = tokens[j++];
                    ip = tokens[j++];
                    pointtype = Convert.ToInt32(tokens[j++]);

                    if (tokens[j].IndexOf("(") == 0)
                    {
                        string temp = tokens[j++];
                        img = Convert.ToInt32(temp.Substring(1, temp.Length - 2));
                    }

                    string xy = tokens[j++];
                    x = Convert.ToInt32(xy.Substring(xy.IndexOf("X=") + 2, xy.IndexOf(',') - (xy.IndexOf("X=") + 2)));
                    y = Convert.ToInt32(xy.Substring(xy.IndexOf("Y=") + 2, xy.IndexOf('}') - (xy.IndexOf("Y=") + 2)));

                    MyPoint mp = addPoint(new Point(x, y), name, location, IPAddress.Parse(ip), pointtype);
                    mp.ID = id;
                    setPointImage(mp, img);

                    //读取节点内包含连线节点                            
                    while (j < tokens.Length && tokens[j].Length > 0)
                    {
                        MyPoint mp2 = findPoint(tokens[j]);
                        if (mp2 != null)
                        {
                            mp.MyDrawLinePoll.Add(mp2);
                            mp2.myDrawLinePoll.Add(mp);
                        }
                        j++;
                    }
                }
            }
        }
               

        private void clear()
        {
            SuspendLayout();            

            //清除节点
            foreach (MyPoint p in pointPoll)
                this.Controls.Remove(p);
            pointPoll.Clear();

            //清除title            
            foreach (Label l in titlePoll)
                this.Controls.Remove(l);
            titlePoll.Clear();

            currentfile = null;

            ResumeLayout();

            Invalidate();
        }

        

        /// <summary>
        /// 保存 按钮定义
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mi_Save_Click_1(object sender, EventArgs e)
        {
            string filename = "";
            if (currentfile != null && currentfile.Length > 0)
                filename = currentfile;
            else if (saveFileDialog1.ShowDialog() == DialogResult.OK)
                filename = saveFileDialog1.FileName;

            if (filename != null && filename.Length > 0)
            {
                File.WriteAllText(filename, "");
                FileStream f = File.Open(filename, FileMode.OpenOrCreate);

                StreamWriter MySW = new StreamWriter(f);
                try
                {
                    MySW.WriteLine(build());
                    MySW.Flush();
                    MySW.Close();
                    MessageBox.Show("保存完毕！");
                }
                catch (Exception ex)
                {
                    MessageBox.Show("保存文本文件失败！" + ex.Message.ToString());
                }
            }
        }

        private string currentfile = null;

        private void MenuItemUpload_Click(object sender, EventArgs e)
        {            
            NetMonClient.GetClient("").writeConfig(build());
            MessageBox.Show("上传完毕，请重开。");
        }


        private string build()
        {                             
            String lines = ""; 
            foreach (MyPoint tmp in pointPoll)
            {
                string line = "";
                if (tmp.ID != null && tmp.ID.Length > 0)
                    line += "(" + tmp.ID + ") ";
                line += tmp.PointName + " ";
                line += tmp.PointLocation + " ";
                line += tmp.PointIpaddress + " ";
                line += tmp.PointType + " ";
                line += "(" + tmp.ImgGroup + ") "; 
                line += tmp.PointPosition + " ";
                
                foreach (MyPoint neighbor in tmp.MyDrawLinePoll)                                            
                    line += neighbor.PointName + " ";

                lines += line + "\r\n";                    
            }

            return lines;    
        }


        /// <summary>
        /// 退出 按钮定义
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mi_Close_Click(object sender, EventArgs e)
        {
            Close();
        }
        #endregion


        #region 视图下拉菜单
        /// <summary>
        /// 属性窗口 按钮定义
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mi_Property_Click_1(object sender, EventArgs e)
        {
            if (leftPanel.Visible == true)
            {
                leftPanel.Visible = mi_Property.Checked = false;
            }
            else
            {
                leftPanel.Visible = mi_Property.Checked = true;
            }

        }
        /// <summary>
        /// 全屏显示 按钮定义
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mi_FullScreen_Click_1(object sender, EventArgs e)
        {
            this.SetVisibleCore(false);
            this.FormBorderStyle = FormBorderStyle.None;
            this.WindowState = FormWindowState.Maximized;
            this.SetVisibleCore(true);
            menuStrip1.Visible = false;
            leftPanel.Visible = tsm_Property.Checked = mi_Property.Checked = false;
            tsm_ExitFullScreen.Enabled = true;
        }

        #endregion


        #region 工具下拉菜单
        /// <summary>
        /// 背景更换 按钮定义
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mi_BackgroundChange_Click(object sender, EventArgs e)
        {
            ChangeBackgroudImage();
        }


        /// <summary>
        /// 选项按钮定义
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mi_Option_Click(object sender, EventArgs e)
        {
            OptionForm of = new OptionForm();
            of.BigPointColor = lbColor;
            of.BigPointFont = lbFont;
            of.LineColor = lineColor;
            of.LineWidth = lineWidth;
            of.ShowDialog();
            if (of.DialogResult == DialogResult.OK)
            {
                lbColor = of.BigPointColor;
                lbFont = of.BigPointFont;
                lineColor = of.LineColor;
                lineWidth = of.LineWidth;
                RefreshAllLabel();
                Refresh();
            }
        }


        /// <summary>
        /// 更改字体后刷新所有Label控件,让字体和颜色改变
        /// </summary>
        private void RefreshAllLabel()
        {
            if (titlePoll.Count > 0)
            {
                for (int i = 0; i < titlePoll.Count; i++)
                {
                    Label tmlb = (Label)titlePoll[i];
                    tmlb.Font = lbFont;
                    tmlb.ForeColor = lbColor;
                    titlePoll[i] = tmlb;
                    RePositionAllLable();
                }
            }
        }


        /// <summary>
        /// 定义完节点字体大小后重新优化字体的位置
        /// </summary>
        private void RePositionAllLable()
        {
            if (pointPoll.Count > 0)
            {
                for (int i = 0; i < pointPoll.Count; i++)
                {
                    MyPoint tpp = (MyPoint)pointPoll[i];
                    foreach (Label tplb in titlePoll)
                    {
                        if (tplb.Name == "lb_" + tpp.PointName)
                        {
                            tplb.Top = tpp.Top - tplb.Height - 10;
                            break;
                        }
                    }
                }
            }
        }

        #endregion


        #region 鼠标右键菜单

        /// <summary>
        /// 右键退出全屏按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsm_ExitFullScreen_Click(object sender, EventArgs e)
        {
            this.SetVisibleCore(false);
            this.FormBorderStyle = FormBorderStyle.FixedSingle;
            this.WindowState = FormWindowState.Maximized;
            this.SetVisibleCore(true);
            menuStrip1.Visible = true;
            leftPanel.Visible = true;
            tsm_ExitFullScreen.Enabled = false;
        }


        /// <summary>
        /// 右键变更背景按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsm_ChangeBackImage_Click(object sender, EventArgs e)
        {
            ChangeBackgroudImage();
        }

        /// <summary>
        /// 右键显示属性窗口按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsm_Property_Click(object sender, EventArgs e)
        {
            if (leftPanel.Visible == true)            
                leftPanel.Visible = tsm_Property.Checked = false;            
            else            
                leftPanel.Visible = tsm_Property.Checked = true;
            
        }



        /// <summary>
        /// 右键详细信息按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsm_Detail_Click(object sender, EventArgs e)
        {            
            MyPoint mp = selectMp;
            lb_PointName.Text = "节点名称: " + mp.PointName;
            lb_PointLocation.Text = "地理位置: " + mp.PointLocation;
            lb_Ipaddress.Text = "I P 地址: " + mp.PointIpaddress.ToString();
            if (!mp.IsDisconnected)
            {
                lb_IsConn.Text = "联通";
                lb_IsConn.ForeColor = Color.Green;
            }
            else
            {
                lb_IsConn.Text = "阻断";
                lb_IsConn.ForeColor = Color.Red;
            }            
        }


        /// <summary>
        /// 右键删除按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsm_Delete_Click(object sender, EventArgs e)
        {
            //注意删除节点不但要把节点从poll里去除,在划线的情况下,线路的对方拥有
            //本节点的实例,需要遍历每个poll中的节点,把其他节点中有自己实例的删除
            if (pointPoll.Contains(selectMp))
            {
                foreach (Label item in titlePoll)
                {
                    if (item.Name == "lb_" + selectMp.PointName)
                    {
                        titlePoll.Remove(item);
                        break;
                    }
                }
                
                //在其他节点里删除自己的实例
                foreach (MyPoint otherp in pointPoll)                
                    otherp.RemovePointFromPool(selectMp);
                
                //最后在poll里删除自己,并从控件上删除自己
                selectMp.StopTimer();
                pointPoll.Remove(selectMp);
                this.Controls.Remove(selectMp);
                this.Controls.Remove(selectLb);
                selectMp = null;
                selectLb = null;
                lb_PointCount.Text = pointPoll.Count.ToString();

                filterPoints(scale);
                refreshTooltips();
                Invalidate();
            }

        }

        /// <summary>
        /// 右键编辑按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsm_EditPoint_Click(object sender, EventArgs e)
        {
            PropertyForm pf = new PropertyForm();
            pf.PointName = selectMp.PointName;
            pf.PointLocation = selectMp.PointLocation;
            pf.PointIpaddress = selectMp.PointIpaddress;
            pf.Location = recordPoint;
            pf.DisplayValue();

            pf.Location = selectMp.Location;
            if (pf.Bottom > this.Bottom)
                pf.Top = this.Bottom - pf.Height - 10;
            if (pf.Right > this.Right)
                pf.Left = this.Right - pf.Width - 10;

            pf.ShowDialog();

            if (pf.DialogResult == DialogResult.OK)
            {
                selectMp.PointName = pf.PointName;
                selectMp.PointLocation = pf.PointLocation;
                selectMp.PointIpaddress = pf.PointIpaddress;

                selectLb.Name = "lb_" + selectMp.PointName;
                selectLb.Text = selectMp.PointName;

                refreshTooltips();
                Invalidate();
            }
        }

        private PointImage pi = new PointImage();
        private void setPointImage(MyPoint p, int g)
        {
            p.ImgGroup = g;
            p.NormalImage = pi.Icons.Images[g * 3];
            p.WarnImage = pi.Icons.Images[g * 3 + 1];
            p.DisConnImage = pi.Icons.Images[g * 3 + 2];
            p.RefreshImage();
        }       

        private void tsm_ChangeIcon_Click(object sender, EventArgs e)
        {            
            pi.ShowDialog();
            if (pi.DialogResult == DialogResult.OK)
            {
                setPointImage(selectMp, pi.ImgGroup);

                selectMp.IsDisconnected = true;
                selectMp.SetDisconImage();
            }
        }

        #endregion


        private bool isEditable = true;

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (isEditable)
            {
                isEditable = false;

                toolStripMenuItem2.Enabled = false;
                toolStripMenuItem3.Enabled = false;
                tsm_ChangeIcon.Enabled = false;

                groupBox1.Enabled = false;
            }
            else
            {
                isEditable = true;

                toolStripMenuItem2.Enabled = true;
                toolStripMenuItem3.Enabled = true;
                tsm_ChangeIcon.Enabled = true;

                groupBox1.Enabled = true;
            }
        }
       
        private void toolTip1_Popup(object sender, PopupEventArgs e)
        {
            if (e.AssociatedControl.GetType().Equals(typeof(MyPoint)))
                e.ToolTipSize = new Size(150, 110);

        }


        #region 私有方法

        /// <summary>
        /// 背景变更的方法
        /// </summary>
        private void ChangeBackgroudImage()
        {
            ChangeBackImageForm cf = new ChangeBackImageForm();
            cf.ShowDialog();
            if (DialogResult.OK == cf.DialogResult)
            {
                String url = null;
                if (cf.ScreenMode == "wide")
                {
                    if (cf.ScreenImage == "wx")
                    {
                        url = StaticPar.wideBackImageUrl + @"\" + StaticPar.wxBackImageUrl;
                    }
                    else if (cf.ScreenImage == "zq")
                    {
                        url = StaticPar.wideBackImageUrl + @"\" + StaticPar.zqBackImageUrl;
                    }
                    else if (cf.ScreenImage == "dx")
                    {
                        url = StaticPar.wideBackImageUrl + @"\" + StaticPar.dxBackImageUrl;
                    }
                }
                else
                {
                    if (cf.ScreenImage == "wx")
                    {
                        url = StaticPar.normalBackImageUrl + @"\" + StaticPar.wxBackImageUrl;
                    }
                    else if (cf.ScreenImage == "zq")
                    {
                        url = StaticPar.normalBackImageUrl + @"\" + StaticPar.zqBackImageUrl;
                    }
                    else if (cf.ScreenImage == "dx")
                    {
                        url = StaticPar.normalBackImageUrl + @"\" + StaticPar.dxBackImageUrl;
                    }
                }
                this.BackgroundImage = Image.FromFile(AppDomain.CurrentDomain.BaseDirectory + @"images\" + url);
            }
        }


        /// <summary>
        /// 划线的方法一,划一条从节点1到节点2之间的直线
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        private void DrawMyLine(MyPoint p1, MyPoint p2, Graphics g)
        {
            bool isnew = false;
            if (g == null)
            {
                g = CreateGraphics();
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                isnew = true;
            }

            //定义画笔
            Pen mypen = new Pen(lineColor);

            foreach (PointLine l in pointLines)
            {
                if (l.myEquals(p1, p2))
                    mypen = new Pen(l.lineColor);
            }
            
            mypen.Width = lineWidth;
            g.DrawLine(mypen, p1.Left + p1.Width/2, p1.Top + p1.Height/2, p2.Left + p2.Width/2, p2.Top + p2.Height/2);
            mypen.Dispose();

            if (isnew)
                g.Dispose();
        }



        /// <summary>
        /// 划线的方法二,在其中调用了划线方法一,把参数mp与之相连的所有直线都划出来
        /// </summary>
        /// <param name="mp"></param>
        private void DrawMyLine(MyPoint mp, Graphics g)
        {
            foreach(MyPoint p in mp.MyDrawLinePoll)
                if (filteredPoints.Contains(p))
                    DrawMyLine(mp, p, g);                
        }




        /// <summary>
        /// 划线CheckBox按钮的动作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cb_DrawLine_CheckedChanged(object sender, EventArgs e)
        {
            if (isEditable)
            {
                if (cb_DrawLine.Checked == true)
                {
                    cb_DrawLine.BackColor = Color.Firebrick;
                    canMovement = canAddNewPoint = false;
                    if (point1 != null || point2 != null)
                    {
                        point1 = point2 = null;
                    }
                    cm_MyPoint.Enabled = false;

                }
                else
                {
                    cb_DrawLine.BackColor = SystemColors.Control;
                    canMovement = canAddNewPoint = true;
                    if (point1 != null || point2 != null)
                    {
                        point1 = point2 = null;
                    }
                    cm_MyPoint.Enabled = true;
                }
            }
        }


        #endregion


        #region 重写方法


        private Bitmap map;
        private int mapZoom = 1;

        /// <summary>
        /// 重写OnPaint,重绘窗体的时候把所有的线画上
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;                   

            g.DrawImage(map, getMapLeft(), getMapTop(), getMapWidth(), getMapHeight());

            base.OnPaint(e);
           
            foreach (MyPoint mytemp in filteredPoints)                
                DrawMyLine(mytemp, g);            
        }

        #endregion

        private int mapMoveHor = 0;
        private int mapMoveVer = 0;

        private int startX = 0;
        private int startY = 0;

        private void MainForm_MouseDown(object sender, MouseEventArgs e)
        {
            Cursor = Cursors.Hand;
            startX = e.X;
            startY = e.Y;
        }

        private void MainForm_MouseUp(object sender, MouseEventArgs e)
        {
            Cursor = Cursors.Default;
            moveMap(startX - e.X, startY - e.Y);          
        }

        private void MainForm_MouseWheel(object sender, MouseEventArgs e)
        {
            if (e.Delta > 0)
                zoomIn(e.X, e.Y);
            else
                zoomOut(e.X, e.Y);
        }

        private void movePoint(MyPoint mp, Point sp)
        {
            mp.PointPosition = caculateMapPoint(sp);

            reCaculatePositions();
        }

        private void moveMap(int deltaScrX, int deltaScrY)
        {
            mapMoveHor = checkMapMoveHor(mapMoveHor + deltaScrX / scale);
            mapMoveVer = checkMapMoveVer(mapMoveVer + deltaScrY / scale);

            reCaculatePositions();  
        }

        private int scale = 1;
        private int scaleStep = 2;

        private void zoomIn(int centerX, int centerY)
        {
            if (scale > 2)
                return;

            int old = scale;
            scale = scale * scaleStep;
            mapMoveHor = checkMapMoveHor(mapMoveHor + centerX / old - centerX / scale);
            mapMoveVer = checkMapMoveVer(mapMoveVer + centerY / old - centerY / scale);

            switchMap(scale);
            filterPoints(scale);
            reCaculatePositions();
        }

        private void zoomOut(int centerX, int centerY)
        {
            if (scale < 2)
                return;

            int old = scale;
            scale = scale / scaleStep;
            if (scale < 1)
                scale = 1;
            mapMoveHor = checkMapMoveHor(mapMoveHor + centerX / old - centerX / scale);
            mapMoveVer = checkMapMoveVer(mapMoveVer + centerY / old - centerY / scale);

            switchMap(scale);
            filterPoints(scale);
            reCaculatePositions();
        }

        private int smallZoom = 1;
        private Bitmap smallMap = Properties.Resources.Map_china5;
        private int mediumZoom = 2;
        private Bitmap mediumMap = Properties.Resources.Map_china6;
        private int largeZoom = 4;
        private Bitmap largeMap = Properties.Resources.Map_china7;

        private void switchMap(int zoom)
        {
            if (zoom == 1)
            {
                map = smallMap;
                mapZoom = smallZoom;
            }
            else if (zoom == 2)
            {
                map = mediumMap;
                mapZoom = mediumZoom;
            }
            else if (zoom == 4)
            {
                map = largeMap;
                mapZoom = largeZoom;
            }            
        }

        private List<MyPoint> filteredPoints = new List<MyPoint>();

        private void filterPoints(int zoom)
        {
            filteredPoints.Clear();
            foreach (MyPoint p in pointPoll)
            {
                if (zoom == 1)
                {
                    if (p.PointType < 3)
                    {
                        p.Visible = true;
                        findLabel(p.PointName).Visible = true;
                        filteredPoints.Add(p);
                    }
                    else
                    {
                        p.Visible = false;
                        findLabel(p.PointName).Visible = false;
                    }
                }
                else
                {
                    p.Visible = true;
                    findLabel(p.PointName).Visible = true;
                    filteredPoints.Add(p);
                }
            }
        }

        private void reCaculatePositions()
        {
            SuspendLayout();

            foreach (MyPoint p in pointPoll)
            {
                Point sp = caculateScreenPoint(p.PointPosition);
                p.Left = sp.X - p.Width / 2;
                p.Top = sp.Y - p.Height / 2;

                Label l = findLabel(p.PointName);
                l.Left = sp.X - l.Width / 2;
                l.Top = p.Top - l.Height - 5;
            }

            ResumeLayout();
            Invalidate();
        }

        private Point caculateMapPoint(Point sp)
        {
            return new Point(sp.X / scale + mapMoveHor, sp.Y / scale + mapMoveVer);
        }

        private Point caculateScreenPoint(Point mp)
        {
            return new Point((mp.X - mapMoveHor) * scale, (mp.Y - mapMoveVer) * scale);
        }

        private int getMapTop()
        {
            return -mapMoveVer * scale;
        }

        private int getMapLeft()
        {
            return -mapMoveHor * scale;            
        }

        private int getMapWidth()
        {            
            if (scale == mapZoom)            
                return map.Width;
            else
                return (int)(map.Width * (double)scale / (double)mapZoom);            
        }

        private int getMapHeight()
        {
            if (scale == mapZoom)            
                return map.Height;            
            else            
                return (int)(map.Height * (double)scale / (double)mapZoom);            
        }

        private int checkMapMoveHor(int mov)
        {
            if (mov < getMinX())
                return getMinX();
            if (mov > getMaxX())
                return getMaxX();
            return mov;
        }

        private int checkMapMoveVer(int mov)
        {
            if (mov < getMinY())
                return getMinY();
            if (mov > getMaxY())
                return getMaxY();
            return mov;
        }

        private int getMinX()
        {
            if (getMapWidth() < this.Width)
                return (getMapWidth() - this.Width) / scale;
            else
                return 0;
        }

        private int getMaxX()
        {
            if (getMapWidth() < this.Width)
                return 0;
            else
                return (getMapWidth() - this.Width) / scale;
        }

        private int getMinY()
        {
            if (getMapHeight() < this.Height)
                return (getMapHeight() - this.Height) / scale;                
            else
                return 0;
        }

        private int getMaxY()
        {
            if (getMapHeight() < this.Height)
                return 0;
            else
                return (getMapHeight() - this.Height) / scale;
        }

        private MyPoint findPoint(string name)
        {
            foreach (MyPoint p in pointPoll)
                if (p.PointName.Equals(name))
                    return p;
            return null;
        }

        private Label findLabel(string name)
        {
            name = "lb_" + name;
            foreach (Label l in titlePoll)
                if (l.Name.Equals(name))
                    return l;
            return null;
        }

        private void generateToolTip(MyPoint p)
        {
            String tips = p.PointName  + "\r\n";
            tips += "所在地区：" + p.PointLocation + "\r\n";
            tips += "网络地址：" + p.PointIpaddress.ToString() + "\r\n";
            tips += "相邻节点：";
            foreach (MyPoint n in p.myDrawLinePoll)                            
                tips += n.PointName + " ";
         
            toolTip1.SetToolTip(p, tips);         
        }

        private void refreshTooltips()
        {
            foreach (MyPoint p in pointPoll)
                generateToolTip(p);
        }

        private MyPoint addPoint(Point p, String name, String location, IPAddress ip, int type)
        {
            if (IfHasPoint(name))
            {
                MessageBox.Show("错误,检测到同名的节点存在.");
                return null;
            }

            MyPoint mp = new MyPoint();

            mp.PointName = name;
            mp.PointLocation = location;
            mp.PointIpaddress = ip;
            mp.PointType = type;
            //节点位置坐标            
            mp.PointPosition = p;
            
            mp.NormalImage = NetMonitor.NetApp.Properties.Resources.normal30;
            mp.WarnImage = NetMonitor.NetApp.Properties.Resources.warning30;
            mp.DisConnImage = NetMonitor.NetApp.Properties.Resources.discon30;
            
            mp.SizeMode = PictureBoxSizeMode.StretchImage;
            mp.SetDisconImage();
            mp.MouseUp += new MouseEventHandler(mp_MouseUp);            
            mp.MouseDown += new MouseEventHandler(mp_MouseDown);
            mp.BackColor = Color.Transparent;
            mp.ContextMenuStrip = this.cm_MyPoint;
  
            //添加节点                            
            if (mp.PointType == 1)
            {
                mp.Height = StaticPar.normalIconBig_Height;
                mp.Width = StaticPar.normalIconBig_Width;
            }
            else if (mp.PointType == 2)
            {
                mp.Height = 24;
                mp.Width = 24;
            }
            else if (mp.PointType == 3)
            {
                mp.Height = 18;
                mp.Width = 18;
            }

            Point sp = caculateScreenPoint(mp.PointPosition);
            mp.Top = sp.Y - mp.Height / 2;
            mp.Left = sp.X - mp.Width / 2;

            //运行时声明一个Lb用来显示节点名称
            Label mptitle = new Label();
            mptitle.Name = "lb_" + mp.PointName;
            mptitle.Text = mp.PointName;
            mptitle.BackColor = Color.Transparent;
            mptitle.ForeColor = lbColor;
            mptitle.Font = lbFont;
            mptitle.AutoSize = true;

            mptitle.Top = mp.Top - 23;
            mptitle.Left = (int)(mp.Left - mptitle.Text.Length * 5.5 + mp.Width / 2.0);

            // 生成提示信息
            generateToolTip(mp);

            pointPoll.Add(mp);
            titlePoll.Add(mptitle);
            this.Controls.Add(mp);
            this.Controls.Add(mptitle);
            
            return mp;
        }

        private Color curLineColor;

        private void button1_Click(object sender, EventArgs e)
        {
            if (colorDialog1.ShowDialog() == DialogResult.OK)
            {
                curLineColor = colorDialog1.Color;
                cb_DrawLine.ForeColor = curLineColor;
            }
        }
        
        
    }

        #endregion
}